/********************************************
* Copyrigt (C) rumi
* Module: View_UartUI.cpp
*********************************************/
#include "View_UartUI.h"

void Init_Uart();

View_UartUI::View_UartUI(QWidget *parent) : QWidget(parent) {

    serialPort = new QSerialPort(this);
    updateTimer = new QTimer(this);

    QPushButton *UartUI_backButton = new QPushButton("Back", this);
    UartUI_backButton->setGeometry(10, 10, 50, 50);
    connect(UartUI_backButton, &QPushButton::clicked, this, &View_UartUI::switchToViewMain);

    QList <QString>UartGroup_List;
    UartGroup_List<<"Info"<<"Setting"<<"Trans";
    int UartGroup_List_Count = UartGroup_List.size();
    QGroupBox *Uartwidget_Info_GroupBox[UartGroup_List_Count];
    QGridLayout *Uart_gridLayout[UartGroup_List_Count];
    for(uint8_t i=0;i<UartGroup_List_Count;i++)
    {
        Uartwidget_Info_GroupBox[i] = new QGroupBox((UartGroup_List[i]), this);
        Uart_gridLayout[i] = new QGridLayout();
    }
    Uartwidget_Info_GroupBox[0]->setGeometry(10, 75, 150, 200);
    Uartwidget_Info_GroupBox[1]->setGeometry(10, 275, 150, 150);
    Uartwidget_Info_GroupBox[2]->setGeometry(825, 375, 150, 150);

    QList <QString>UartInfoList;
    UartInfoList<<"Port"<<"Speed"<<"DataBit"<<"StopBit"<<"Check";
    QList <QString>UartComboList_Port;
    UartComboList_Port<<"NUll";
    // QList <QString>UartComboList_Speed;
    // UartComboList_Speed<<"9600"<<"57600"<<"115200";
    QList <QString>UartComboList_Datalen;
    UartComboList_Datalen<<"8";
    QList <QString>UartComboList_StopBit;
    UartComboList_StopBit<<"1"<<"2";
    QList <QString>UartComboList_Check;
    UartComboList_Check<<"none"<<"check";

    int UartInfoList_Count = UartInfoList.size();

    int UartComboList_Port_Count = UartComboList_Port.size();
    // int UartComboList_Speed_Count = UartComboList_Speed.size();
    int UartComboList_Datalen_Count = UartComboList_Datalen.size();
    int UartComboList_StopBit_Count = UartComboList_StopBit.size();
    int UartComboList_Check_Count = UartComboList_Check.size();
    for(int i = 0; i < UartInfoList_Count; i++) 
    {
        Uart_Info_label[i] = new QLabel();
        Uartwidget_Info_ComboBox[i] = new QComboBox();
        Uart_Info_label[i]->setText(UartInfoList[i]);
        switch (i)
        {
            case 0:     // PORT
                Uart_gridLayout[0]->addWidget(Uart_Info_label[i], i, 0);
                Uart_gridLayout[0]->addWidget(Uartwidget_Info_ComboBox[i], i, 1);
                for(int im = 0;im < UartComboList_Port_Count;im++)
                {
                    Uartwidget_Info_ComboBox[i]->addItem(UartComboList_Port[im]);
                }
                break;
            case 1:     // Speed
                Uart_gridLayout[0]->addWidget(Uart_Info_label[i], i, 0);
                Uart_gridLayout[0]->addWidget(Uartwidget_Info_ComboBox[i], i, 1);
                Uartwidget_Info_ComboBox[i]->addItem("9600", QSerialPort::Baud9600);
                Uartwidget_Info_ComboBox[i]->addItem("19200", QSerialPort::Baud19200);
                Uartwidget_Info_ComboBox[i]->addItem("57600", QSerialPort::Baud57600);
                Uartwidget_Info_ComboBox[i]->addItem("115200", QSerialPort::Baud115200);           
                break;
            case 2:     // DataBitLen
                Uart_gridLayout[0]->addWidget(Uart_Info_label[i], i, 0);
                Uart_gridLayout[0]->addWidget(Uartwidget_Info_ComboBox[i], i, 1);
                for(int im = 0;im < UartComboList_Datalen_Count;im++)
                {
                    Uartwidget_Info_ComboBox[i]->addItem(UartComboList_Datalen[im]);
                }
                break;
            case 3:     // StopBit
                Uart_gridLayout[0]->addWidget(Uart_Info_label[i], i, 0);
                Uart_gridLayout[0]->addWidget(Uartwidget_Info_ComboBox[i], i, 1);
                for(int im = 0;im < UartComboList_StopBit_Count;im++)
                {
                    Uartwidget_Info_ComboBox[i]->addItem(UartComboList_StopBit[im]);
                }
                break;
            case 4:     // Check
                Uart_gridLayout[0]->addWidget(Uart_Info_label[i], i, 0);
                Uart_gridLayout[0]->addWidget(Uartwidget_Info_ComboBox[i], i, 1);
                for(int im = 0;im < UartComboList_Check_Count;im++)
                {
                    Uartwidget_Info_ComboBox[i]->addItem(UartComboList_Check[im]);
                }
                break;
            default:
                break;
        }
    }
    Uartwidget_Info_GroupBox[0]->setLayout(Uart_gridLayout[0]);

    QList <QString> UartSetList_PushButton;
    UartSetList_PushButton<<"Open Uart"<<"Clear"<<"Save";
    int UartSetList_PushButton_Count = UartSetList_PushButton.size();
    
    for(uint8_t i=0;i<UartSetList_PushButton_Count;i++)
    {
        Uartwidget_Info_PushButton[i] = new QPushButton();
        Uartwidget_Info_PushButton[i]->setText(UartSetList_PushButton[i]);
        Uartwidget_Info_PushButton[i]->setMinimumSize(100, 30);
        Uart_gridLayout[1]->addWidget(Uartwidget_Info_PushButton[i], i, 0);
    }
    Uartwidget_Info_GroupBox[1]->setLayout(Uart_gridLayout[1]);
    connect(Uartwidget_Info_PushButton[0], &QPushButton::clicked, this, &View_UartUI::openSerialPort);
    connect(Uartwidget_Info_PushButton[1], &QPushButton::clicked, this, &View_UartUI::clearSerialRecv);

    QDir::setCurrent(QCoreApplication::applicationDirPath());

    Uartwidget_TR_PlainTextEdit = new QPlainTextEdit(this);
    Uartwidget_TR_PlainTextEdit->setGeometry(200, 10, 800, 350);
    Uartwidget_TR_PlainTextEdit->setReadOnly(true);

    Uartwidget_TR_TextEdit = new QTextEdit(this);
    Uartwidget_TR_TextEdit->setGeometry(200, 375, 600, 150);
    
    QPushButton *Uartwidget_TR_PushButton[2];
    Uartwidget_TR_PushButton[0] = new QPushButton();
    Uartwidget_TR_PushButton[0]->setText("Send");
    Uartwidget_TR_PushButton[1] = new QPushButton();
    Uartwidget_TR_PushButton[1]->setText("Clear");
    Uart_gridLayout[2]->addWidget(Uartwidget_TR_PushButton[0], 0, 0);
    Uart_gridLayout[2]->addWidget(Uartwidget_TR_PushButton[1], 1, 0);
    connect(Uartwidget_TR_PushButton[0], &QPushButton::clicked, this, &View_UartUI::sendSerialData);
    connect(Uartwidget_TR_PushButton[1], &QPushButton::clicked, this, &View_UartUI::clearSerialSend);

    Uartwidget_Info_GroupBox[2]->setLayout(Uart_gridLayout[2]);

    connect(serialPort, &QSerialPort::readyRead, this, &View_UartUI::reciveSerialData);
    connect(updateTimer, &QTimer::timeout, this, &View_UartUI::updateAvailablePorts);
    
    updateTimer->start(1000);
    updateAvailablePorts();

    sendThread = new SendThread(this);
    receiveThread = new ReceiveThread(this);

    connect(sendThread, &SendThread::sendData, this, &View_UartUI::writeSerialData);
    //connect(receiveThread, &ReceiveThread::requestRead, this, &View_UartUI::readSerialData);

    sendThread->start();
    //receiveThread->start();

}

void Init_Uart()
{
    QList<QSerialPortInfo> serialPortInfos = QSerialPortInfo::availablePorts();
    int serialPortInfos_Count = serialPortInfos.size();
    if (serialPortInfos.isEmpty()) {
        qDebug() << "No serial ports found.";
#if 0  // display serial port info
    } else {
        for (int i = 0; i < serialPortInfos_Count; i++) {
            // Print details of each serial port
            qDebug() << "Port Name: " << serialPortInfos[i].portName();
            qDebug() << "Description: " << serialPortInfos[i].description();
            qDebug() << "Manufacturer: " << serialPortInfos[i].manufacturer();
        }
#endif // DEBUG
    }
}


void View_UartUI::updateAvailablePorts() {
    QString currentPort = Uartwidget_Info_ComboBox[0]->currentText();
    Uartwidget_Info_ComboBox[0]->clear();
    QList<QSerialPortInfo> ports = QSerialPortInfo::availablePorts();
    for (const QSerialPortInfo &info : ports) {
        Uartwidget_Info_ComboBox[0]->addItem(info.portName());
    }

    int index = Uartwidget_Info_ComboBox[0]->findText(currentPort);
    if (index != -1) {
        Uartwidget_Info_ComboBox[0]->setCurrentIndex(index);
    }
}

void View_UartUI::openSerialPort() {
    if (serialPort->isOpen()) {
        serialPort->close();
        Uartwidget_Info_PushButton[0]->setText("Open");
        Uartwidget_TR_PlainTextEdit->appendPlainText("Serial port closed.");
        return;
    }

    serialPort->setPortName(Uartwidget_Info_ComboBox[0]->currentText());
    serialPort->setBaudRate(Uartwidget_Info_ComboBox[1]->currentData().toInt());
    //serialPort->setBaudRate(QSerialPort::Baud115200);

#ifdef Uart_ShowUartSpeed  // display serial port baud speed
    int portSpeed = Uartwidget_Info_ComboBox[1]->currentData().toInt();
    QString portSpeedString = QString::number(portSpeed);
    QString portSpeedDescription = "Port Speed: ";
    Uartwidget_TR_PlainTextEdit->appendPlainText(portSpeedDescription + portSpeedString);
#endif // DEBUG

    serialPort->setDataBits(QSerialPort::Data8);
    serialPort->setParity(QSerialPort::NoParity);
    serialPort->setStopBits(QSerialPort::OneStop);
    serialPort->setFlowControl(QSerialPort::NoFlowControl);

    if (serialPort->open(QIODevice::ReadWrite)) {
        Uartwidget_Info_PushButton[0]->setText("Close");
        Uartwidget_TR_PlainTextEdit->appendPlainText("Serial port opened successfully.");
    } else {
        Uartwidget_TR_PlainTextEdit->appendPlainText("Failed to open serial port.");
    }
}

// void View_UartUI::sendSerialData() {
//     if (serialPort->isOpen() && serialPort->isWritable()) {
//         QString data = Uartwidget_TR_TextEdit->toPlainText();
//         serialPort->write(data.toUtf8());
//         Uartwidget_TR_PlainTextEdit->appendPlainText("Sent: " + data);
//     } else {
//         Uartwidget_TR_PlainTextEdit->appendPlainText("Failed to send data. Serial port is not open.");
//     }
// }

void View_UartUI::reciveSerialData() {
    if (serialPort->isOpen() && serialPort->isReadable()) {
        QByteArray data = serialPort->readAll();
        QString timestamp = QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss.zzz");
        Uartwidget_TR_PlainTextEdit->appendPlainText("Received: " + timestamp + ": " + QString::fromUtf8(data));
    }
}

void View_UartUI::clearSerialRecv(){
    Uartwidget_TR_PlainTextEdit->clear();
}

void View_UartUI::clearSerialSend(){
    Uartwidget_TR_TextEdit->clear();
}

void View_UartUI::writeSerialData(const QString &data) {
    if (serialPort->isWritable()) {
        serialPort->write(data.toUtf8());
        Uartwidget_TR_PlainTextEdit->appendPlainText("Thread Sent: " + data);
    }
}

void View_UartUI::readSerialData() {
    if (serialPort->isReadable()) {
        QByteArray data = serialPort->readAll();
        QString timestamp = QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss.zzz");
        Uartwidget_TR_PlainTextEdit->appendPlainText("Thread Received: " + timestamp + ": " + QString::fromUtf8(data));
    }
}

void View_UartUI::sendSerialData() {
    QString data = Uartwidget_TR_TextEdit->toPlainText();
    if (!data.isEmpty()) {
        sendThread->enqueueData(data);
        //Uartwidget_TR_TextEdit->clear();
    }
}
/********************************************
 * End of file
*********************************************/
